package com.dynamic.datasource.router;

import org.springframework.core.NamedThreadLocal;
import org.springframework.util.StringUtils;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @author 王先堂
 * @Description 数据源上下文
 * @createTime 2022/03/28/ 15:20:00
 */
public final class DataSourceContext {

    /**
     * 数据源名称,栈结构存储，先进后出，支持在多数据源相互调用
     */
    private static final ThreadLocal<Deque<String>> DATASOURCE_NAME_LOCAL = new NamedThreadLocal<Deque<String>>("datasource_context") {
        @Override
        protected Deque<String> initialValue() {
            return new ArrayDeque<>();
        }
    };

    /**
     * 获取当前线程数据源名称
     *
     * @return 数据源名称
     */
    public static String get() {
        return DATASOURCE_NAME_LOCAL.get().peek();
    }

    /**
     * 添加当前线程数据源名称
     *
     * @param name 数据源名称
     * @return 数据源名称
     */
    public static String add(String name) {
        String dataSourceStr = StringUtils.isEmpty(name) ? "" : name;
        DATASOURCE_NAME_LOCAL.get().push(dataSourceStr);
        return dataSourceStr;
    }

    /**
     * 移除当前线程数据源名称
     */
    public static void remove() {
        Deque<String> deque = DATASOURCE_NAME_LOCAL.get();
        deque.poll();
        if (deque.isEmpty()) {
            DATASOURCE_NAME_LOCAL.remove();
        }
    }

    /**
     * 清除所有线程数据源名称
     */
    public static void clearAll() {
        DATASOURCE_NAME_LOCAL.remove();
    }
}
